﻿Imports System
Imports System.ComponentModel.Design
Imports System.ComponentModel.Design.Serialization
Imports System.Globalization
Imports System.IO
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Design
Imports System.Workflow.ComponentModel.Serialization
Imports System.Xml

Namespace System.Workflow.ComponentModel
    Public NotInheritable Class AddedActivityAction
        Inherits ActivityChangeAction
        ' Methods
        Public Sub New()
        End Sub

        Public Sub New(ByVal compositeActivity As CompositeActivity, ByVal activityAdded As Activity)
            MyBase.New(compositeActivity)
            If (compositeActivity Is Nothing) Then
                Throw New ArgumentNullException("compositeActivity")
            End If
            If (activityAdded Is Nothing) Then
                Throw New ArgumentNullException("activityAdded")
            End If
            Me.index = If((Not compositeActivity.Activities Is Nothing), compositeActivity.Activities.IndexOf(activityAdded), -1)
            Me.addedActivity = activityAdded
        End Sub

        Protected Friend Overrides Function ApplyTo(ByVal rootActivity As Activity) As Boolean
            If (rootActivity Is Nothing) Then
                Throw New ArgumentNullException("rootActivity")
            End If
            If Not TypeOf rootActivity Is CompositeActivity Then
                Throw New ArgumentException(SR.GetString("Error_RootActivityTypeInvalid"), "rootActivity")
            End If
            Dim compositeActivity As CompositeActivity = [TryCast](rootActivity.TraverseDottedPathFromRoot(MyBase.OwnerActivityDottedPath),CompositeActivity)
            If (compositeActivity Is Nothing) Then
                Return False
            End If
            compositeActivity.DynamicUpdateMode = True
            Dim parent As CompositeActivity = Me.addedActivity.Parent
            Try 
                Me.addedActivity.SetParent(compositeActivity)
                Dim addedActivity As Activity = Me.addedActivity
                If Not Me.addedActivity.DesignMode Then
                    addedActivity = Me.addedActivity.Clone
                Else
                    Dim serviceInstance As TypeProvider = WorkflowChanges.CreateTypeProvider(rootActivity)
                    Dim provider As New ServiceContainer
                    provider.AddService(GetType(ITypeProvider), serviceInstance)
                    Dim manager As New DesignerSerializationManager(provider)
                    Dim serializer As New WorkflowMarkupSerializer
                    Dim s As String = String.Empty
                    [Using] manager.CreateSession
                        [Using] writer As StringWriter = New StringWriter(CultureInfo.InvariantCulture)
                            [Using] writer2 As XmlWriter = Helpers.CreateXmlWriter(writer)
                                Dim serializationManager As New WorkflowMarkupSerializationManager(manager)
                                serializer.Serialize(serializationManager, writer2, Me.addedActivity)
                                s = writer.ToString
                            End [Using]
                        End [Using]
                        [Using] reader As StringReader = New StringReader(s)
                            [Using] reader2 As XmlReader = XmlReader.Create(reader)
                                Dim manager3 As New WorkflowMarkupSerializationManager(manager)
                                addedActivity = [TryCast](serializer.Deserialize(manager3, reader2),Activity)
                            End [Using]
                        End [Using]
                    End [Using]
                    If (addedActivity Is Nothing) Then
                        Throw New InvalidOperationException(SR.GetString("Error_ApplyDynamicChangeFailed"))
                    End If
                End If
                If (Not compositeActivity.WorkflowCoreRuntime Is Nothing) Then
                    DirectCast(addedActivity, IDependencyObjectAccessor).InitializeInstanceForRuntime(compositeActivity.WorkflowCoreRuntime)
                End If
                addedActivity.SetParent(Nothing)
                compositeActivity.Activities.Insert(Me.index, addedActivity)
            Finally
                Me.addedActivity.SetParent(parent)
                compositeActivity.DynamicUpdateMode = False
            End Try
            Return True
        End Function


        ' Properties
        Property AddedActivity As Activity
            Public Get
                Return Me.addedActivity
            End Get
            Friend Set(ByVal value As Activity)
                Me.addedActivity = value
            End Set
        End Property

        Property Index As Integer
            Public Get
                Return Me.index
            End Get
            Friend Set(ByVal value As Integer)
                Me.index = value
            End Set
        End Property


        ' Fields
        Private addedActivity As Activity
        Private index As Integer
    End Class
End Namespace

